import time
from time import sleep

from jenkinsapi.jenkins import Jenkins
from django.conf import settings

JENKINS_URL = f"http://{settings.SERVER_HOST}:9090"
# JENKINS_URL = f"http://192.168.146.129:9090"
# JENKINS_URL = "http://jenkins:8080"
JENKINS_USERNAME = "biantianyi"
JENKINS_PASSWORD = "111111"
JENKINS_API_TOKEN = "myapitoken"


class JenkinsSdk:
    jenkins_client = None

    @classmethod
    def get_jenkins_client(cls):
        if cls.jenkins_client is None:
            cls.jenkins_client = Jenkins(JENKINS_URL, username=JENKINS_USERNAME, password=JENKINS_PASSWORD)
            return cls.jenkins_client
        else:
            return cls.jenkins_client

    def get_job_list(self):
        jenkins_client = self.get_jenkins_client()
        job_objs = jenkins_client.get_jobs_list()
        data = {}
        for job in job_objs:
            if "test" in job or "server" in job:
                job_obj = jenkins_client.get_job(job)
                params_list = []
                if job_obj.has_params():
                    for p in job_obj.get_params():
                        params = {}
                        params["type"] = p.get("type")
                        params["name"] = p.get("name")
                        params["default"] = p.get("defaultParameterValue").get("value")
                        params["description"] = p.get("description")
                        params["choices"] = p.get("choices")
                        params_list.append(params)
                if last_build := job_obj.get_last_build_or_none():
                    build_data = last_build._data
                    content = {
                        "last_build_name": build_data['fullDisplayName'],

                        "build_time": time.strftime("%Y-%m-%d %H:%M:%S",
                                                    time.localtime(build_data['timestamp'] // 1000)),
                        "build_status": build_data['result'],
                        "allure_report": build_data["url"] + 'allure/' if len(build_data["artifacts"]) else None,
                        "params": params_list if params_list else None
                    }
                else:
                    content = {
                        "last_build_name": "无构建",
                        "build_time": None,
                        "build_status": None,
                        "allure_report": None,
                        "params": params_list if params_list else None
                    }
                data.update({job_obj.name: content})
        return {
            'job_objs': job_objs,
            "data": data
        }

    def get_job_info(self, name):
        # job_obj = self.jenkins_client.get_job(name)
        job_obj = self.get_job_obj(name)
        build_data = job_obj.get_last_build()._data
        return {
            "last_build_name": build_data['fullDisplayName'],

            "build_time": time.strftime("%Y-%m-%d %H:%M:%S",
                                        time.localtime(build_data['timestamp'] // 1000)),
            "build_status": build_data['result'],
            "allure_report": build_data["url"] + 'allure/' if len(build_data["artifacts"]) else None,
        }

    def build_job(self, job_name, **kwargs):
        # jenkins_client = self.get_jenkins_client()
        # job_obj = jenkins_client.get_job(job_name)
        job_obj = self.get_job_obj(job_name)
        if job_obj.is_queued_or_running():
            return "当前构建正在执行"
        else:
            if job_obj.has_params():
                job_obj.invoke(build_params=kwargs)
            else:
                job_obj.invoke()
            return 'ok'

    def get_console(self, job_name):
        # jenkins_client = self.get_jenkins_client()
        # job_obj = jenkins_client.get_job(job_name)
        job_obj = self.get_job_obj(job_name)
        if last_build := job_obj.get_last_build_or_none():
            last_num = job_obj.get_last_completed_buildnumber()
        else:
            last_num = 0
        if job_obj.is_queued_or_running():
            for i in range(5):
                try:
                    last_build = job_obj.get_build(last_num + 1)
                    break
                except:
                    pass
                sleep(3)
            return last_build.stream_logs()
        else:
            if last_build:
                return last_build._data['fullDisplayName'] + '\n' + last_build.get_console().encode(
                    "ISO-8859-1").decode('utf8')
            else:
                return '暂无构建信息'

    def get_job_obj(self, job_name):
        jenkins_client = self.get_jenkins_client()
        try:
            job_obj = jenkins_client.get_job(job_name)
        except:
            job_objs = jenkins_client.get_jobs_list()
            temp = job_objs[0].split('/')
            temp.pop()
            remote_url = '/'.join(temp)
            job_obj = jenkins_client.get_job(remote_url + job_name)
        return job_obj


if __name__ == '__main__':
    bb = JenkinsSdk.get_jenkins_client()
    # print(bb.get_job("test_case_mobile").get_last_build().get_resultset())
    aa = JenkinsSdk()
    # para = {'session_timeout': 60, 'session_num': 5, 'server_name': "selenium_server1", 'command': "new", 'port': 4444}

    # print(aa.build_job("selenium_server", **para))
    print(aa.get_console("selenium_server"))
